import sys
import ToE.find_new_traffic as fnt
import ToE.max_min_fairness as mmf
import TE.lp as lp
import numpy as np
import pandas as pd

import read_func as rf

def histogram_intersection(rep: np.ndarray, com: np.ndarray):
    row_num, col_num = rep.shape

    vector1 = rep.reshape(row_num * col_num)
    vector2 = com.reshape(row_num * col_num)

    sm = 0
    for i in range(row_num * col_num):
        sm += min(vector1[i], vector2[i])
    res = sm / vector2.sum()

    return res


def ToE_TE(traffic_arr, pod_num, a_link_bandwidth, link_num, which_row, traffic_num):
    traffic_seq = traffic_arr[which_row : which_row + traffic_num]
    bandwidth_upper_bound = a_link_bandwidth * link_num
    # 此处利用了先限流再分流算法在worst-case情况下的性能保证，用一组流量矩阵推导出一个新的流量矩阵
    new_traffic, S, virtual_r_array = fnt.get_new_traffic(traffic_seq, True, bandwidth_upper_bound)
    topo = mmf.Topology()
    topo = topo.topology([new_traffic], pod_num, a_link_bandwidth, link_num)
    # NOTICE: 拓扑工程代码也能够支持多traffic同时输入求解
    # topo = topo.topology(traffic_seq, pod_num, a_link_bandwidth, link_num)
    
    shape = topo.shape
    capacity = np.array(topo)
    print('topo:')
    print(capacity)
    capacity = capacity.reshape(1, shape[0] * shape[1])
    pd.DataFrame(capacity).to_csv(f'./config/{pod_num}pod_topo.csv', header = False, index = False)

    ret = lp.Routing(topo)
    # 此处仅为了演示routing计算过程，故只取任意一个流量矩阵来计算
    # 实际不断地往后迭代计算traffic_num个流量矩阵，并利用histogram_intersection()来减少计算次数
    traffic = traffic_arr[which_row + traffic_num + 1]
    w_routing = ret.routing(pod_num, a_link_bandwidth, traffic)

    return w_routing


if __name__ == "__main__":
    pod_num = 4
    a_link_bandwidth = 100
    link_num = 20
    which_row = 0    # 哪一行流量开始作ToE和TE
    traffic_num = 5  # 用traffic_num行流量来做ToE和TE

    traffic_file = './traffic/' + str(pod_num) + 'pod_traffic.csv'
    traffic_arr = rf.get_traffic(traffic_file)
    w_routing = ToE_TE(traffic_arr, pod_num, a_link_bandwidth, link_num, which_row, traffic_num)
    print('routing result:')
    print(w_routing)